#include "directoryHandler.h"

using namespace std;

directoryHandler::directoryHandler(const string* dirPath) {
	this->directoryPath = *dirPath;

}

directoryHandler::~directoryHandler() {
}


void directoryHandler::setDirectoryPath(const string* dirPath){
	this->directoryPath = *dirPath;
}

int directoryHandler::getNumberOfFiles() const {
	DIR *dir = opendir(this->directoryPath.c_str());
	struct stat buffer;
	struct dirent *ent;
	int contador = 0;
	char path[255];
	while ((ent = readdir(dir)) != NULL) {
		//Esto es para ignorar subdirectorios
		sprintf(path, "%s/%s", this->directoryPath.c_str(), ent->d_name);
		lstat(path, &buffer);
		if (!S_ISDIR(buffer.st_mode))
			contador++;
	}
	closedir(dir);
	return contador;
}

void directoryHandler::generateListOfFiles(const string* outPath) const {
	DIR *dir = opendir(this->directoryPath.c_str());
	struct stat buffer;
	struct dirent *ent;
	FILE* fd = fopen(outPath->c_str(), "w");
	char path[255];
	std::vector<std::string> result;
	while ((ent = readdir(dir)) != NULL) {
		//Esto es para ignorar subdirectorios
		sprintf(path, "%s/%s", this->directoryPath.c_str(), ent->d_name);
		lstat(path, &buffer);
		if (!S_ISDIR(buffer.st_mode)) {
			//voy poniendo los nombres en un vector, para despues ordenarlo
			result.push_back(std::string(ent->d_name));
		}
		std::sort(result.begin(), result.end());
	}
	//Escribo cada nombre en el archivo
	for (unsigned int i = 0; i < result.size(); i++) {
		fputs(result[i].c_str(), fd);
		fputc(10, fd);

	}
	fclose(fd);
	closedir(dir);
}

std::vector<std::string> directoryHandler::getFilesNames() const {
	DIR *dir = opendir(this->directoryPath.c_str());
	struct stat buffer;
	struct dirent *ent;
	char path[255];
	std::vector<std::string> result;

	while ((ent = readdir(dir)) != NULL) {
		//Esto es para ignorar subdirectorios
		sprintf(path, "%s/%s", this->directoryPath.c_str(), ent->d_name);
		lstat(path, &buffer);
		if (!S_ISDIR(buffer.st_mode)) {
			//voy poniendo los nombres en un vector, para despues ordenarlo
			result.push_back(std::string(ent->d_name));
		}
		std::sort(result.begin(), result.end());
	}

	closedir(dir);
	return result;
}

std::vector<std::string> directoryHandler::getFilesPaths() const {
	DIR *dir = opendir(this->directoryPath.c_str());
	struct stat buffer;
	struct dirent *ent;
	char path[255];
	std::vector<std::string> result;

	while ((ent = readdir(dir)) != NULL) {
		//Esto es para ignorar subdirectorios
		sprintf(path, "%s/%s", this->directoryPath.c_str(), ent->d_name);
		lstat(path, &buffer);
		if (!S_ISDIR(buffer.st_mode)) {
			//voy poniendo los nombres en un vector, para despues ordenarlo
			result.push_back(
					std::string(
							std::string(this->directoryPath) + "/"
									+ ent->d_name));
		}
	}

	std::sort(result.begin(), result.end());
	closedir(dir);
	return result;

}

void directoryHandler::deleteFiles(bool recursive) const {
	vector<string> v = this->getFilesNames();

	char* p;
	if (!recursive) {
		for (unsigned int i = 0; i < v.size(); i++) {
			string s;
			s = (this->directoryPath);
			s = s + "/" + (v.at(i));
			asprintf(&p, "rm %s", s.c_str());
			system(p);
			free(p);
			}
	} else {
		DIR *dir = opendir(this->directoryPath.c_str());
		struct dirent *ent;
		while ((ent = readdir(dir)) != NULL) {
			char *fileName = ent->d_name;
			if (fileName[0] != '.') {
				string s;
				s = (this->directoryPath);
				s = s + "/" + fileName;
				asprintf(&p, "rm -rf %s", s.c_str());
				system(p);
				free(p);

			}
		}
		closedir(dir);
	}

}

bool directoryHandler::folderExists(const string* name) const {
	DIR *dir = opendir(this->directoryPath.c_str());
	struct stat buffer;
	struct dirent *ent;
	char path[255];
	std::vector<std::string> result;

	while ((ent = readdir(dir)) != NULL) {
		sprintf(path, "%s/%s", this->directoryPath.c_str(), ent->d_name);
		lstat(path, &buffer);
		if (S_ISDIR(buffer.st_mode)) {
			//voy poniendo los directorios en result
			result.push_back(
					std::string(
							std::string(this->directoryPath) + "/"
									+ ent->d_name));
		}
	}

	//Me fijo si el name está en el vector
	bool existe = false;
	unsigned int i = 0;
	while ((!existe) && (i < result.size())) {
		string n = this->directoryPath;
		n = n + "/" + *name;
		existe = (result.at(i)) == n;
		i++;
	}
	closedir(dir);
	return existe;
}

void directoryHandler::deleteFolder(const string* name) const {
	if (this->folderExists(name)) {
		char *p;
		string s;
		s = (this->directoryPath);
		s = s + "/" + *name;
		asprintf(&p, "rm -rf %s", s.c_str());
		system(p);
		free(p);
	}
}

bool directoryHandler::fileExists(const string* name) const {
	DIR *dir = opendir(this->directoryPath.c_str());
	struct stat buffer;
	struct dirent *ent;
	char path[255];
	std::vector<std::string> result;

	while ((ent = readdir(dir)) != NULL) {
		//Esto es para ignorar subdirectorios
		sprintf(path, "%s/%s", this->directoryPath.c_str(), ent->d_name);
		lstat(path, &buffer);
		if (!S_ISDIR(buffer.st_mode)) {
			//voy poniendo los archivos en result
			result.push_back(
					std::string(
							std::string(this->directoryPath) + "/"
									+ ent->d_name));
		}
	}

	//Me fijo si el name está en el vector
	bool existe = false;
	unsigned int i = 0;
	while ((!existe) && (i < result.size())) {
		string n = this->directoryPath;
		n = n + "/" + *name;
		existe = (result.at(i)) == n;
		i++;
	}
	closedir(dir);
	return existe;
}

void directoryHandler::deleteFile(const string* name) const {
	if (this->fileExists(name)) {

				char* p;
		string s;
		s = (this->directoryPath);
		s = s + "/" + *name;
		const char* file_name = s.c_str();
		remove(file_name);
	}
}

void directoryHandler::createFolder(const string* name) const {
	if (!folderExists(name)) {
		char* p;
		string s;
		s = (this->directoryPath);
		s = s + "/" + *name;
		asprintf(&p, "mkdir %s", s.c_str());
		system(p);
		free(p);
	}
}

void directoryHandler::moveFile(const string* name, const string* newPath) const {
			string s;
			s = (this->directoryPath);
			s = s + "/" + *name;
			string c;
			c="mv "+s+" "+*newPath;
			system(c.c_str());


}

